#include "Int_SN65HVD.h"

/**
 * @brief  CAN驱动初始化
 * @param  baudrate: 波特率选择
 * @retval None
 */
void CAN_Driver_Init(uint8_t baudrate)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    CAN_InitTypeDef CAN_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    // 使能时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

    // 配置CAN引脚 PA11(RX) PA12(TX)
    // PA11 CAN_RX
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // PA12 CAN_TX
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // CAN初始化
    CAN_DeInit(CAN1);
    CAN_StructInit(&CAN_InitStructure);

    // CAN基本配置
    CAN_InitStructure.CAN_TTCM = DISABLE;         // 时间触发通信模式
    CAN_InitStructure.CAN_ABOM = ENABLE;          // 自动离线管理
    CAN_InitStructure.CAN_AWUM = ENABLE;          // 自动唤醒模式
    CAN_InitStructure.CAN_NART = DISABLE;         // 非自动重传输模式
    CAN_InitStructure.CAN_RFLM = DISABLE;         // 接收FIFO锁定模式
    CAN_InitStructure.CAN_TXFP = ENABLE;          // 发送FIFO优先级
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; // 模式

    // 波特率配置 (假设APB1时钟36MHz)
    switch (baudrate)
    {
    case CAN_BAUDRATE_1M: // 1Mbps
        CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
        CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
        CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
        CAN_InitStructure.CAN_Prescaler = 4;
        break;

    case CAN_BAUDRATE_500K: // 500Kbps
        CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
        CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
        CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
        CAN_InitStructure.CAN_Prescaler = 8;
        break;

    case CAN_BAUDRATE_250K: // 250Kbps
        CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
        CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
        CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
        CAN_InitStructure.CAN_Prescaler = 16;
        break;

    case CAN_BAUDRATE_125K: // 125Kbps
    default:
        CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
        CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
        CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
        CAN_InitStructure.CAN_Prescaler = 32;
        break;
    }

    // 初始化CAN
    if (CAN_Init(CAN1, &CAN_InitStructure) != CAN_InitStatus_Success)
    {
        // 初始化失败处理
        while (1)
            ;
    }

    // 配置过滤器
    CAN_Filter_Config();

    // 配置CAN中断
    NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    // 使能接收中断
    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
}

/**
 * @brief  配置CAN过滤器
 * @param  None
 * @retval None
 */
void CAN_Filter_Config(void)
{
    CAN_FilterInitTypeDef CAN_FilterInitStructure;

    CAN_FilterInitStructure.CAN_FilterNumber = 0; // 过滤器0
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; // 接收所有ID
    CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0; // 分配给FIFO0
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);
}

/**
 * @brief  发送CAN消息
 * @param  msg: 消息指针
 * @retval 0=失败, 1=成功
 */
uint8_t CAN_Send_Message(CAN_Message_t *msg)
{
    CanTxMsg TxMessage;
    uint8_t TransmitMailbox;
    uint32_t timeout = 0;

    // 填充发送消息
    TxMessage.StdId = msg->StdId;
    TxMessage.ExtId = msg->ExtId;
    TxMessage.IDE = msg->IDE;
    TxMessage.RTR = msg->RTR;
    TxMessage.DLC = msg->DLC;

    for (uint8_t i = 0; i < 8; i++)
    {
        TxMessage.Data[i] = msg->Data[i];
    }

    // 发送消息
    TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);

    // 等待发送完成
    while ((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK) && (timeout < 0xFFFF))
    {
        timeout++;
    }

    if (timeout >= 0xFFFF)
    {
        return 0; // 发送失败
    }

    return 1; // 发送成功
}

/**
 * @brief  接收CAN消息
 * @param  msg: 消息指针
 * @retval 0=无消息, 1=接收成功
 */
uint8_t CAN_Receive_Message(CAN_Message_t *msg)
{
    CanRxMsg RxMessage;

    if (CAN_MessagePending(CAN1, CAN_FIFO0) == 0)
    {
        return 0; // 无消息
    }

    // 接收消息
    CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);

    // 填充接收消息
    msg->StdId = RxMessage.StdId;
    msg->ExtId = RxMessage.ExtId;
    msg->IDE = RxMessage.IDE;
    msg->RTR = RxMessage.RTR;
    msg->DLC = RxMessage.DLC;

    for (uint8_t i = 0; i < 8; i++)
    {
        msg->Data[i] = RxMessage.Data[i];
    }

    return 1; // 接收成功
}

/**
 * @brief  CAN接收中断服务函数
 * @param  None
 * @retval None
 */
void USB_LP_CAN1_RX0_IRQHandler(void)
{
    CAN_Message_t RxMsg;

    if (CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)
    {
        // 接收消息
        Delay_ms(100);
        if (CAN_Receive_Message(&RxMsg))
        {
            if (RxMsg.IDE == CAN_Id_Standard)
            {
                debug_printfln("receive msg: %x", RxMsg.StdId);
            }
            else if (RxMsg.IDE == CAN_Id_Extended)
            {
                debug_printfln("receive msg: %x", RxMsg.ExtId);
            }
        }
        else
        {
            debug_printfln("receive msg fail");
        }

        CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
    }
}

// 静默回环测试
void Simple_LoopBack_Test(void)
{
    CAN_Message_t TxMsg, RxMsg;

    // 使用静默回环模式初始化
    CAN_Driver_Init(CAN_BAUDRATE_500K);

    // 准备测试消息
    TxMsg.StdId = 0x123;
    TxMsg.IDE = CAN_Id_Standard;
    TxMsg.RTR = CAN_RTR_Data;
    TxMsg.DLC = 8;
    TxMsg.Data[0] = 0xAA;
    TxMsg.Data[1] = 0x55;
    TxMsg.Data[2] = 0xFF;
    TxMsg.Data[3] = 0x00;
    TxMsg.Data[4] = 0x12;
    TxMsg.Data[5] = 0x34;
    TxMsg.Data[6] = 0x56;
    TxMsg.Data[7] = 0x78;

    while (1)
    {
        // 发送测试消息
        if (CAN_Send_Message(&TxMsg))
        {
            // 等待并接收消息
            Delay_ms(100);
            if (CAN_Receive_Message(&RxMsg))
            {
                // 验证数据
                if (RxMsg.StdId == TxMsg.StdId)
                {
                    debug_printfln("test success! ID:0x%03X\r\n", RxMsg.StdId);
                }
            }
            else
            {
                debug_printfln("receive msg fail");
            }
        }
        else
        {
            debug_printfln("send msg fail");
        }

        Delay_ms(1000);
    }
}

// ... existing code ...
void can_extended_frame_test(void)
{
    CAN_Message_t TxMsg, RxMsg;

    // 初始化CAN，使用回环模式，波特率500K
    CAN_Driver_Init(CAN_BAUDRATE_500K);

    // 配置扩展帧消息示例
    TxMsg.StdId = 0x000;         // 标准ID部分（在扩展帧中仍然需要设置）
    TxMsg.ExtId = 0x12345678;    // 扩展ID (29位)
    TxMsg.IDE = CAN_Id_Extended; // 设置为扩展帧格式
    TxMsg.RTR = CAN_RTR_Data;    // 数据帧
    TxMsg.DLC = 8;               // 数据长度
    TxMsg.Data[0] = 0x11;
    TxMsg.Data[1] = 0x22;
    TxMsg.Data[2] = 0x33;
    TxMsg.Data[3] = 0x44;
    TxMsg.Data[4] = 0x55;
    TxMsg.Data[5] = 0x66;
    TxMsg.Data[6] = 0x77;
    TxMsg.Data[7] = 0x88;

    while (1)
    {
        // 发送扩展帧消息
        if (CAN_Send_Message(&TxMsg))
        {
            debug_printfln("Extended frame sent successfully");

            // 等待并接收消息
            Delay_ms(100);
            if (CAN_Receive_Message(&RxMsg))
            {
                // 验证接收到的数据
                if (RxMsg.IDE == CAN_Id_Extended && RxMsg.ExtId == TxMsg.ExtId)
                {
                    debug_printfln("Extended frame test success! ID:0x%08X", RxMsg.ExtId);
                    debug_printfln("Data: %02X %02X %02X %02X %02X %02X %02X %02X",
                                   RxMsg.Data[0], RxMsg.Data[1], RxMsg.Data[2], RxMsg.Data[3],
                                   RxMsg.Data[4], RxMsg.Data[5], RxMsg.Data[6], RxMsg.Data[7]);
                }
                else
                {
                    debug_printfln("Received frame ID mismatch");
                }
            }
            else
            {
                debug_printfln("Failed to receive extended frame");
            }
        }
        else
        {
            debug_printfln("Failed to send extended frame");
        }

        Delay_ms(2000);
    }
}
